#ifndef _XXXPCSC_THREAD_H_
#define _XXXPCSC_THREAD_H_

//C++11之前 pthread_xxx
///C++之后 std::thread, <-pthread_xxx

#include<thread>
#include<functional>  //线程执行方法
#include<memory>
//互斥用pthread更好写
#include<pthread.h>
#include<semaphore.h>
#include<stdint.h>

namespace xxXPCSC{

    //Semaphore 读写分离
    class Semaphore{
    public:
        Semaphore(uint32_t count=0);
        ~Semaphore();

        void wait();
        void notify();
    private:
        //禁用拷贝构造
        Semaphore(const Semaphore&) = delete;
        Semaphore(const Semaphore&&) = delete;
        Semaphore& operator=(const Semaphore&) = delete;
    private:
        sem_t m_semaphore;
    };

    //构造函数加锁 析构函数解锁 局部变量生命周期实现锁的获取与释放
    template<class T>
    struct ScopedLockImpl{
    public:
        ScopedLockImpl(T& mutex):m_mutex(mutex){
            m_mutex.lock();
            m_locked=true;
        }
        ~ScopedLockImpl(){
            unlock();
        }
        void lock(){
            if(!m_locked){
                m_mutex.lock();
                m_locked=true;
            }
        }
        void unlock(){
            if(m_locked){
                m_mutex.unlock();
                m_locked=false;
            }
        }
    private:
        T& m_mutex;
        bool m_locked;
    };

    template<class T>
    struct ReadScopedLockImpl{
    public:
        ReadScopedLockImpl(T& mutex):m_mutex(mutex){
            m_mutex.rdlock();
            m_locked=true;
        }
        ~ReadScopedLockImpl(){
            unlock();
        }
        void lock(){
            if(!m_locked){
                m_mutex.rdlock();
                m_locked=true;
            }
        }
        void unlock(){
            if(m_locked){
                m_mutex.unlock();
                m_locked=false;
            }
        }
    private:
        T& m_mutex;
        bool m_locked;
    };
    template<class T>
    struct WriteScopedLockImpl{
    public:
        WriteScopedLockImpl(T& mutex):m_mutex(mutex){
            m_mutex.wrlock();
            m_locked=true;
        }
        ~WriteScopedLockImpl(){
            unlock();
        }
        void lock(){
            if(!m_locked){
                m_mutex.wrlock();
                m_locked=true;
            }
        }
        void unlock(){
            if(m_locked){
                m_mutex.unlock();
                m_locked=false;
            }
        }
    private:
        T& m_mutex;
        bool m_locked;
    };
    
    //互斥量 分读写锁
    class RWMutex{
    public:
        typedef ReadScopedLockImpl<RWMutex> ReadLock;
        typedef WriteScopedLockImpl<RWMutex> WriteLock;
        RWMutex(){
            pthread_rwlock_init(&m_lock,nullptr);
        }
        ~RWMutex(){
            pthread_rwlock_destroy(&m_lock);
        }
        void rdlock(){
            pthread_rwlock_rdlock(&m_lock);
        }
        void wrlock(){
            pthread_rwlock_wrlock(&m_lock);
        }
        void unlock(){
            pthread_rwlock_unlock(&m_lock);
        }
    private:
        pthread_rwlock_t m_lock; 
    };

    class Thread{
    public:
        //typedef long int tid_t;
        typedef std::shared_ptr<Thread> ptr;

        Thread(std::function<void()> cb,const std::string& name);
        ~Thread();

        const pid_t getId(){return m_id;}
        const std::string& getName(){return m_name;}
        
        void join();

        static Thread* GetThis();
        static const std::string& GetName();
        static void SetName(const std::string& name);
    private:
        //C++11新特性 禁用默认拷贝构造 互斥量不能拷贝 拷贝破坏其作用
        Thread(const Thread&) = delete;
        Thread(const Thread&&) = delete;
        Thread&operator=(const Thread&) = delete;

        static void* run(void* arg);
    private:
        //tid_t本身的类型同pid_t是一个long int类型 在之前typedef C++11之中应该没有tid_t关键字
        pid_t m_id = -1;
        pthread_t m_thread = 0;
        std::function<void()> m_cb;   //函数的包装 m_cb = 一个无参无返回值函数调用
        std::string m_name;
        Semaphore m_semaphore;
    };
}




#endif
